﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Web;
using JXT.PrimaryKey.Batman.Core.WcfService;
using JXT.PrimaryKey.Batman.WcfService.Models;
using JXT.PrimaryKey.Batman.WcfService.Interfaces;
using JXT.PrimaryKey.Batman.WcfService.Client.Wrapper;

namespace JXT.PrimaryKey.Batman.WcfService.Client
{
    public sealed class ServiceFactory : IServiceFactory {
        public string BaseUrl { get; set; }

        public string AuthenticationId { get; set; }

        public string AuthenticationKey { get; set; }

        private WebChannelFactory<IUser> _userChannelFactory;
        private IUser _userService;

        private WebChannelFactory<IQuotation> _quotationChannelFactory;
        private IQuotation _quotationService;

        private static readonly string _userUrl = "/user";
        private static readonly string _quotationUrl = "/quotation";

        public static IServiceFactory Create(string baseUrl) {
            return new ServiceFactory(baseUrl);
        }

        private ServiceFactory(string baseUrl) {
            if (String.IsNullOrEmpty(baseUrl))
                throw new ArgumentNullException("baseUrl");
            baseUrl = baseUrl.Replace('\\', '/');
            if (baseUrl.EndsWith("/")) {
                baseUrl = baseUrl.Remove(baseUrl.Length - 1);
            }
            BaseUrl = baseUrl;
        }

        private Uri buildUrl(string url) {
            Uri result;
            if (!Uri.TryCreate(BaseUrl + url, UriKind.RelativeOrAbsolute, out result)) {
                throw new ArgumentException("url string can not convert to url object.");
            }
            return result;
        }

        public IUser CreateUserService() {
            if (_userChannelFactory == null) {
                _userChannelFactory = new WebChannelFactory<IUser>(buildUrl(_userUrl));
                _userService = _userChannelFactory.CreateChannel();
            }
            return new UserWrapperService(_userService, AuthenticationId, AuthenticationKey);
        }

        public IQuotation CreateQuotaionService()
        {
            if (_quotationChannelFactory == null)
            {
                _quotationChannelFactory = new WebChannelFactory<IQuotation>(buildUrl(_userUrl));
                _quotationService = _quotationChannelFactory.CreateChannel();
            }
            return new QuotationWrapperService(_quotationService, AuthenticationId, AuthenticationKey);
        }

        public void Dispose() {
            if (_userChannelFactory != null)
                _userChannelFactory.Close();
            if (_quotationChannelFactory != null)
                _quotationChannelFactory.Close();
        }
    }
}
